#ifndef __tenacitas_id_concept__string2number__h__
#define __tenacitas_id_concept__string2number__h__



/** @file */


/** @todo */

// ==> C++ Headers
#include <string>
#include <cstring>
#include <cstdint>

// ==> 3rds Headers

// ==> Our Headers

// ==> Namespaces
using namespace std;

// ==> Macro Constants

// ==> Macro Commands

/** ==> namespace of the organization */
namespace tenacitas {
    /** ==> namespace for the project */
    namespace id {
        /** ==> application, bussiness, display, interaction, process, storage,
            transmittion */
        namespace concept {

            // ==> Typedefs 

            // ==> Pre-Declarations

            // ==> Attributes 

            // ==> Functions

            // ==> Classes

            /**

               @throw std::invalid_argument
               @throw std::out_of_range 
            */
            template <typename tp_num, uint8_t base = 10>
            struct s2n;

            template <>
            struct s2n<int16_t> {

                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                template <typename tp_str>
                int16_t operator()(tp_str p_str) {
                    return stoi(p_str);
                }

                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                int16_t operator()(const char * p_str) {
                    return atoi(p_str);
                }
            };

            template <>
            struct s2n<int32_t> {
                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                template <typename tp_str>
                int32_t operator()(tp_str p_str) {
                    return stol(p_str);
                }

                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                int32_t operator()(const char * p_str) {
                    return atol(p_str);
                }
            };

            template <>
            struct s2n<int64_t> {
                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                template <typename tp_str>
                int64_t operator()(tp_str p_str) {
                    return stoll(p_str);
                }

                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                int64_t operator()(const char * p_str) {
                    return atoll(p_str);
                }
            };

            template <>
            struct s2n<uint16_t> {
                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                template <typename tp_str>
                uint16_t operator()(tp_str p_str){
                    return static_cast<uint16_t>(stoi(p_str));
                }

                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                uint16_t operator()(const char * p_str) {
                    return static_cast<uint16_t>(atoi(p_str));
                }
            };

            template <>
            struct s2n<uint32_t> {
                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                template <typename tp_str>
                uint32_t operator()(tp_str p_str) {
                    return stoul(p_str);
                }

                uint32_t operator()(const char * p_str) {
                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                    return atol(p_str);
                }
            };

            template <>
            struct s2n<uint64_t> {
                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                template <typename tp_str>
                uint64_t operator()(tp_str p_str) {
                    return stoull(p_str);
                }

                /**

                   @throw std::invalid_argument
                   @throw std::out_of_range 
                */
                uint64_t operator()(const char * p_str) {
                    char * l_end = nullptr;
                    return strtoull(p_str, &l_end, 10);
                }
            };
            

        }
    }
}
// =============================================================================
// I M P L E M E N T A T I O N
// =============================================================================

using namespace tenacitas::id::concept;



#endif
